package com.tripspins.app.helper;

import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.tripspins.app.NewPinActivity;
import com.tripspins.app.interfaces.UpdateMapListener;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.model.LatLng;

import java.util.List;

public class LocationHelper implements
        LocationListener,
        GooglePlayServicesClient.ConnectionCallbacks,
        GooglePlayServicesClient.OnConnectionFailedListener{
    private Context context;
    private static Geocoder geocoder;
    private static LocationHelper locationHelperInstance;
    long minTime = 0;
    float minDistance = 10;
    Location location;
    LocationRequest locationRequest;
    LocationClient locationClient;
    UpdateMapListener map;

    public static LocationHelper getInstance(Context context, UpdateMapListener map)
    {
        if (locationHelperInstance==null)
            locationHelperInstance = new LocationHelper(context, map);
        else if (locationHelperInstance.map == null)
        {
            locationHelperInstance.map = map;
        }

        return locationHelperInstance;
    }
    public static LocationHelper getInstance(Context context)
    {
        if (locationHelperInstance==null)
            locationHelperInstance = new LocationHelper(context, null);
        return locationHelperInstance;
    }

    public boolean isAPIReady()
    {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
        if (ConnectionResult.SUCCESS == resultCode)
            return true;
        else
            return false;

    }

    private LocationHelper(Context context, UpdateMapListener map)
    {
        this.map = map;
        this.context = context;
        LocationManager locationManager = (LocationManager) this.context.getSystemService(context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);


        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(minTime);
        locationRequest.setFastestInterval(minTime);
        locationRequest.setSmallestDisplacement(minDistance);


        locationClient = new LocationClient(context,this,this);

        locationClient.connect();


        //locationManager.requestLocationUpdates(locationManager.NETWORK_PROVIDER,minTime,minDistance,this);
        //locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER,minTime,minDistance,this);


    }


    public double getAltitude()
    {
        return location.getAltitude();

    }

    public float getSpeed()
    {
        return location.getSpeed();
    }

    public Address getAddress()
    {
        Address address = null;
        List<Address> list = null;

        LatLng position = getPosition();
        try{

            list =  geocoder.getFromLocation(position.latitude, position.longitude,1);
        }
        catch(Exception e){}

        if (list!= null && list.size() > 0)
            address = list.get(0);
        return address;
    }

    public static Address getAddress(LatLng latLng)
    {
        Address address = null;
        List<Address> list = null;
        try{

            list =  geocoder.getFromLocation(latLng.latitude, latLng.longitude,1);
        }
        catch(Exception e){}

        if (list!= null && list.size() > 0)
            address = list.get(0);
        return address;
    }

    public LatLng getPosition() {
        LatLng position = null;
        if (location != null) {
            position = new LatLng(
                    location.getLatitude(),
                    location.getLongitude());
        }
        return position;
    }

    public void onLocationChanged(Location location) {
        this.location = location;
        if(map != null)
            map.updateMapLocation(new LatLng(location.getLatitude(),location.getLongitude()));
    }

    public void onProviderDisabled(String provider) {
        Log.i("trips", provider);
        // TODO Auto-generated method stub

    }

    public void onProviderEnabled(String provider) {
        Log.i("trips", provider);
        // TODO Auto-generated method stub

    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub
        Log.i("trips", provider);

    }


    public double distance(LatLng position, LatLng newPosition) {
        if(position == null || newPosition == null) return 0;
        return Math.sqrt(Math.pow(newPosition.latitude - position.latitude, 2) + Math.pow(newPosition.longitude - position.longitude, 2));
    }

    @Override
    public void onConnected(Bundle bundle) {
        Toast.makeText(context, "conectou location", Toast.LENGTH_LONG);
        locationClient.requestLocationUpdates(locationRequest,this);
    }

    @Override
    public void onDisconnected() {
        Toast.makeText(context, "desconectou location", Toast.LENGTH_LONG);
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Toast.makeText(context, "erro location", Toast.LENGTH_LONG);
    }

    public void stopListening()
    {
        locationClient.disconnect();
        locationHelperInstance = null;
    }
}
